<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>基层AI辅助诊断系统 - 通知管理</title>
    <link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
    <script src="https://unpkg.com/vue@3"></script>
    <script src="https://unpkg.com/element-plus"></script>
    <script src="https://unpkg.com/element-plus/dist/locale/zh-cn.min.js"></script>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
            background: #FFFFFF; color: var(--text-primary); font-size: 14px; line-height: 1.5; margin: 0;
        }
        :root {
            --primary: #0F6CBD; --primary-light: #D0E7FF; --primary-dark: #0A4F8D;
            --success: #0F8A5F; --warning: #F59337; --error: #D13438; --info: #0078D4;
            --text-primary: #1A1A1A; --text-secondary: #4D4D4D; --text-tertiary: #767676; --text-disabled: #A6A6A6;
            --border-strong: #CCCCCC; --border-normal: #E0E0E0; --border-light: #F0F0F0; --divider: #F5F5F5;
            --bg-primary: #FFFFFF; --bg-secondary: #F9F9F9; --bg-card: #FFFFFF; --bg-disabled: #F5F5F5;
            --medical-critical: #B91C1C; --medical-abnormal: #F59E0B; --medical-normal: #10B981; --medical-pending: #3B82F6; --medical-completed: #9CA3AF;
            --spacing-2: 2px; --spacing-4: 4px; --spacing-8: 8px; --spacing-12: 12px; --spacing-16: 16px; --spacing-24: 24px; --spacing-32: 32px; --spacing-40: 40px; --spacing-48: 48px;
            --font-page-title: 20px; --font-card-title: 16px; --font-table-title: 14px; --font-body: 14px; --font-table: 13px; --font-small: 12px;
            --line-height-title: 1.4; --line-height-body: 1.5; --line-height-table: 1.2; --line-height-form: 1.4;
            --radius-small: 2px; --radius-medium: 4px;
            --transition-fast: 150ms; --transition-normal: 200ms; --transition-slow: 300ms;
            --nav-item-width: 140px;
        }
        .container { width: 100%; min-height: 100vh; display: flex; flex-direction: column; background-color: var(--bg-secondary); }
        .header { height: 60px; background-color: var(--bg-primary); border-bottom: 1px solid var(--border-normal); display: flex; align-items: center; padding: 0 var(--spacing-24); box-shadow: 0 2px 4px rgba(0,0,0,0.05); position: relative; z-index: 100; }
        .header-spacer { width: 200px; flex-shrink: 0; }
        #app-nav { position: absolute; left: 50%; transform: translateX(-50%); z-index: 10; width: calc(100% - 400px); display: flex; justify-content: center; }
        .el-menu { border: none !important; background-color: transparent !important; }
        .el-menu--horizontal > .el-menu-item,
        .el-menu--horizontal > .el-sub-menu .el-sub-menu__title { height: 60px; line-height: 60px; color: var(--text-secondary); font-weight: 500; font-size: var(--font-body); padding: 0; width: var(--nav-item-width); text-align: center; display: flex; align-items: center; justify-content: center; position: relative; }
        .el-sub-menu__icon-arrow { display: none !important; }
        .el-menu--horizontal > .el-sub-menu .el-sub-menu__title::after { content: ''; display: inline-block; width: 16px; height: 16px; margin-left: 8px; background-repeat: no-repeat; background-position: center; background-size: 16px 16px; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23767676' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>"); }
        .el-sub-menu:hover > .el-sub-menu__title::after, .el-sub-menu.is-active > .el-sub-menu__title::after { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%230F6CBD' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>"); }
        .el-sub-menu.is-opened > .el-sub-menu__title::after { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%230F6CBD' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 15 12 9 18 15'/></svg>"); }
        .el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-sub-menu.is-active .el-sub-menu__title { color: var(--primary) !important; border-bottom: 2px solid var(--primary); font-weight: 500; }
        .el-menu--horizontal > .el-menu-item:not(.is-disabled):hover,
        .el-menu--horizontal > .el-menu-item:not(.is-disabled):focus,
        .el-menu--horizontal > .el-sub-menu:not(.is-disabled):hover .el-sub-menu__title { color: var(--primary); background-color: transparent; }
        .el-menu--popup { width: var(--nav-item-width) !important; min-width: var(--nav-item-width) !important; max-width: var(--nav-item-width) !important; border-radius: var(--radius-small); padding: 4px 0; border: 1px solid var(--border-light); border-top: 2px solid var(--primary); box-shadow: 0 2px 8px rgba(0,0,0,0.1); text-align: center !important; }
        .el-menu--popup .el-menu-item { height: 36px; line-height: 36px; padding: 0 !important; color: var(--text-secondary); white-space: nowrap; text-align: center; width: var(--nav-item-width) !important; box-sizing: border-box; overflow: hidden; text-overflow: ellipsis; display: flex !important; justify-content: center !important; align-items: center !important; font-size: var(--font-body); }
        .el-menu--popup .el-menu-item:hover { background-color: var(--bg-secondary); color: var(--primary); }
        .user-section { display: flex; align-items: center; gap: var(--spacing-16); margin-left: auto; z-index: 10; width: 200px; justify-content: flex-end; flex-shrink: 0; cursor: pointer; padding: 8px 12px; border-radius: var(--radius-small); transition: background-color var(--transition-fast); color: var(--text-secondary); }
        .user-section:hover { background-color: var(--bg-secondary); }
        .user-name { font-weight: 500; font-size: var(--font-body); color: var(--text-secondary); }
        .user-arrow { color: var(--text-tertiary); transition: color var(--transition-normal); }
        .user-section:hover .user-arrow { color: var(--primary); }

        .main-content { padding: 0; flex: 1; background-color: var(--bg-primary); width: 100%; }
        .combined-header { display: flex; justify-content: space-between; align-items: center; padding: var(--spacing-24); border-bottom: 1px solid var(--border-light); background-color: var(--bg-primary); }
        .page-title { font-size: var(--font-page-title); font-weight: 600; color: var(--text-primary); line-height: var(--line-height-title); margin-right: var(--spacing-24); white-space: nowrap; }
        .filter-container { display: flex; align-items: center; gap: var(--spacing-16); flex-wrap: nowrap; }
        .search-box { position: relative; width: 240px; }
        .search-icon { position: absolute; left: 8px; top: 50%; transform: translateY(-50%); color: var(--text-tertiary); pointer-events: none; }
        .search-box input { width: 100%; padding: var(--spacing-8) var(--spacing-8) var(--spacing-8) 32px; border: 1px solid var(--border-normal); border-radius: var(--radius-small); font-size: 14px; color: var(--text-primary); transition: border-color 0.2s, box-shadow 0.2s; height: 32px; }
        .search-box input:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 2px rgba(15,108,189,0.2); }
        .select, .date-input { height: 32px; border: 1px solid var(--border-normal); border-radius: var(--radius-small); padding: 0 var(--spacing-12); font-size: var(--font-body); color: var(--text-primary); }
        .date-separator { color: var(--text-secondary); font-size: var(--font-body); }
        .btn { padding: var(--spacing-8) var(--spacing-16); border-radius: var(--radius-small); font-size: var(--font-body); font-weight: 500; cursor: pointer; border: none; display: inline-flex; align-items: center; justify-content: center; transition: all var(--transition-normal); gap: var(--spacing-8); height: 32px; line-height: 1; }
        .btn-primary { background-color: var(--primary); color: #fff; }
        .btn-primary:hover { background-color: var(--primary-dark); }
        .btn-default { background-color: var(--bg-primary); color: var(--text-secondary); border: 1px solid var(--border-normal); }
        .btn-default:hover { background-color: var(--bg-secondary); }

        .table-section { padding: var(--spacing-24); display: flex; flex-direction: column; gap: var(--spacing-24); background-color: var(--bg-primary); }
        .table-container { background-color: var(--bg-primary); border-radius: var(--radius-small); box-shadow: 0 1px 3px rgba(0,0,0,0.05); overflow: auto; margin-bottom: var(--spacing-16); border: 1px solid var(--border-light); }
        .data-table { width: 100%; border-collapse: collapse; }
        .data-table th { background-color: var(--bg-secondary); padding: var(--spacing-12) var(--spacing-16); text-align: left; font-weight: 600; color: var(--text-secondary); border-bottom: 1px solid var(--border-normal); height: 40px; font-size: var(--font-table-title); }
        .data-table td { padding: var(--spacing-12) var(--spacing-16); border-bottom: 1px solid var(--border-light); color: var(--text-secondary); height: 40px; vertical-align: middle; font-size: var(--font-table); }
        .data-table tr:hover { background-color: var(--bg-secondary); }
        .operations { display: inline-flex; gap: var(--spacing-8); }
        .operation-link { color: var(--primary); text-decoration: none; cursor: pointer; }
        .operation-link:hover { color: var(--primary-dark); }
        .empty-table-message { text-align: center; color: var(--text-tertiary); padding: var(--spacing-16); font-style: italic; }

        .table-footer { display: flex; justify-content: space-between; align-items: center; padding: var(--spacing-16) var(--spacing-24); }
        .pagination-text { color: var(--text-tertiary); font-size: var(--font-small); }
        .pagination-controls { display: flex; align-items: center; gap: var(--spacing-24); }
        .page-numbers { display: flex; gap: var(--spacing-8); }
        .page-numbers button { min-width: 32px; height: 32px; border-radius: var(--radius-small); border: 1px solid var(--border-normal); background: var(--bg-primary); cursor: pointer; color: var(--text-secondary); transition: all var(--transition-normal); display: flex; align-items: center; justify-content: center; font-size: var(--font-small); }
        .page-numbers button:hover { border-color: var(--primary); color: var(--primary); }
        .page-numbers button.active { background: var(--primary); border-color: var(--primary); color: #FFFFFF; }
        .pagination-size { display: flex; align-items: center; gap: var(--spacing-8); color: var(--text-secondary); font-size: var(--font-small); }
        .page-size-selector { height: 32px; border: 1px solid var(--border-normal); border-radius: var(--radius-small); padding: 0 var(--spacing-8); font-size: var(--font-small); margin: 0 var(--spacing-4); }

        /* 弹窗 */
        .modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); display: none; align-items: center; justify-content: center; z-index: 1000; }
        .modal { background-color: var(--bg-primary); border-radius: var(--radius-small); box-shadow: 0 4px 16px rgba(0,0,0,0.1); width: 720px; max-width: 90%; max-height: 90vh; display: flex; flex-direction: column; overflow: hidden; }
        .modal-header { padding: var(--spacing-16) var(--spacing-24); border-bottom: 1px solid var(--border-light); display: flex; align-items: center; justify-content: space-between; }
        .modal-title { font-size: var(--font-card-title); font-weight: 600; color: var(--text-primary); }
        .modal-close { background: none; border: none; cursor: pointer; color: var(--text-tertiary); font-size: 20px; display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 50%; }
        .modal-close:hover { background-color: var(--bg-secondary); color: var(--text-secondary); }
        .modal-body { padding: var(--spacing-24); overflow-y: auto; }
        .modal-footer { padding: var(--spacing-16) var(--spacing-24); border-top: 1px solid var(--border-light); display: flex; justify-content: flex-end; gap: var(--spacing-16); }
        .form-group { margin-bottom: var(--spacing-16); }
        .form-label { display: block; margin-bottom: var(--spacing-8); font-weight: 500; color: var(--text-secondary); }
        .form-control { width: 100%; padding: var(--spacing-8) var(--spacing-12); border: 1px solid var(--border-normal); border-radius: var(--radius-small); font-size: var(--font-body); color: var(--text-primary); transition: border-color var(--transition-normal); height: 36px; }
        .form-control:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 2px rgba(15,108,189,0.2); }
        textarea.form-control { min-height: 120px; resize: vertical; }

        /* 采用用户管理页的多选下拉样式（作用于发布弹窗），保证弹窗层级与尺寸 */
        #publishModal .el-popper { z-index: 2000 !important; }
        #publishModal .el-select__popper { z-index: 2000 !important; }
        #publishModal .el-select-dropdown { max-height: 300px !important; }
        #publishModal .role-select-dropdown { max-height: 300px !important; overflow-y: auto !important; z-index: 2000 !important; }

        /* 原生自定义多选（与规范一致的样式） */
        #publishModal .native-multi-select { position: relative; }
        #publishModal .native-multi-select .trigger {
            display: flex; align-items: center; flex-wrap: wrap; gap: 8px; min-height: 36px;
            border: 1px solid var(--border-normal); border-radius: var(--radius-small);
            background: var(--bg-primary); padding: 6px 32px 6px 8px; cursor: pointer;
        }
        #publishModal .native-multi-select .trigger:focus-within {
            border-color: var(--primary); box-shadow: 0 0 0 2px rgba(15,108,189,0.2);
        }
        #publishModal .native-multi-select .input { border: none; outline: none; flex: 1; min-width: 120px; background: transparent; color: var(--text-primary); cursor: pointer; }
        #publishModal .native-multi-select .arrow { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); color: var(--text-tertiary); pointer-events: none; }
        #publishModal .native-multi-select .tags { display: flex; gap: 6px; flex-wrap: wrap; }
        #publishModal .native-multi-select .tag { background: var(--primary-light); color: var(--primary); border-radius: var(--radius-small); padding: 2px 8px; font-size: 12px; display: inline-flex; align-items: center; gap: 6px; }
        #publishModal .native-multi-select .tag .remove { width: 14px; height: 14px; display: inline-flex; align-items: center; justify-content: center; color: var(--primary); cursor: pointer; }
        #publishModal .native-multi-select .dropdown {
            position: absolute; left: 0; right: 0; top: calc(100% + 4px); background: var(--bg-primary);
            border: 1px solid var(--border-light); border-top: 2px solid var(--primary);
            border-radius: var(--radius-small); box-shadow: 0 2px 8px rgba(0,0,0,0.1); max-height: 300px; overflow: auto; z-index: 2000;
        }
        #publishModal .native-multi-select .option { padding: 8px 12px; color: var(--text-secondary); display: flex; align-items: center; gap: 8px; cursor: pointer; }
        #publishModal .native-multi-select .option:hover { background: var(--bg-secondary); color: var(--primary); }
        /* 选中态不加底色，仅主色文字，保持与规范一致 */
        #publishModal .native-multi-select .option.selected { background: var(--bg-primary); color: var(--primary); }
        #publishModal .native-multi-select .option.selected:hover { background: var(--bg-primary); color: var(--primary); }
        #publishModal .native-multi-select .option input { pointer-events: none; }

        /* 富文本编辑器样式（遵循规范tokens） */
        #publishModal .rte { border: 1px solid var(--border-normal); border-radius: var(--radius-small); background: var(--bg-primary); }
        #publishModal .rte-toolbar { display:flex; flex-wrap: wrap; gap: 8px; padding: 8px; border-bottom: 1px solid var(--border-light); background: var(--bg-secondary); }
        #publishModal .rte-btn { height: 28px; padding: 0 10px; border: 1px solid var(--border-normal); background: var(--bg-primary); color: var(--text-secondary); border-radius: var(--radius-small); cursor: pointer; font-size: 12px; }
        #publishModal .rte-btn:hover { border-color: var(--primary); color: var(--primary); }
        #publishModal .rte-sep { width: 1px; background: var(--border-light); margin: 0 4px; }
        #publishModal .rte-content { min-height: 180px; padding: 12px; color: var(--text-primary); line-height: 1.5; }
        #publishModal .rte-content:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px rgba(15,108,189,0.2); }
        #publishModal .rte-content[placeholder]:empty:before { content: attr(placeholder); color: var(--text-tertiary); }

        /* 通知详情弹窗（简洁网格与标签-值样式） */
        #detailModal .detail-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 16px; }
        #detailModal .detail-item .label { font-size: 12px; color: var(--text-tertiary); margin-bottom: 4px; }
        #detailModal .detail-item .value { color: var(--text-primary); }
        #detailModal .content-box { border: 1px solid var(--border-light); padding: 12px; border-radius: var(--radius-small); background: var(--bg-primary); }

        /* 响应式 */
        @media (max-width: 768px) {
            .header { flex-wrap: wrap; padding: var(--spacing-12) var(--spacing-16); height: auto; }
            .header-spacer { width: 100%; justify-content: center; margin-bottom: 8px; }
            #app-nav { position: relative; left: 0; transform: none; width: 100%; order: 3; margin-top: var(--spacing-8); }
            .combined-header { flex-direction: column; align-items: flex-start; gap: var(--spacing-16); }
            .filter-container { flex-wrap: wrap; }
            .search-box { width: 100%; }
            .table-footer { flex-direction: column; gap: var(--spacing-16); align-items: flex-start; }
            .pagination-controls { flex-direction: column; gap: var(--spacing-16); align-items: flex-start; width: 100%; }
            .page-numbers { flex-wrap: wrap; }
        }
    </style>
</head>
<body>
    <div id="app" class="container">
        <header class="header">
            <div class="header-spacer"></div>
            <div id="app-nav">
                <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect" :ellipsis="false" :popper-offset="0" popper-class="custom-dropdown">
                    <el-menu-item index="1">开始问诊</el-menu-item>
                    <el-sub-menu index="2" popper-class="custom-dropdown">
                        <template #title>病历管理</template>
                        <el-menu-item index="2-1">病历查询</el-menu-item>
                        <el-menu-item index="2-2">病历模板</el-menu-item>
                        <el-menu-item index="2-3">个人药品</el-menu-item>
                    </el-sub-menu>
                    <el-menu-item index="3">患者管理</el-menu-item>
                    <el-sub-menu index="4" popper-class="custom-dropdown">
                        <template #title>数据统计</template>
                        <el-menu-item index="4-1">诊断统计</el-menu-item>
                        <el-menu-item index="4-2">宏观统计</el-menu-item>
                    </el-sub-menu>
                    <el-menu-item index="5">医学知识</el-menu-item>
                    <el-sub-menu index="6" popper-class="custom-dropdown">
                        <template #title>基础数据</template>
                        <el-menu-item index="6-1">药品管理</el-menu-item>
                    </el-sub-menu>
                    <el-sub-menu index="7" popper-class="custom-dropdown">
                        <template #title>消息通知</template>
                        <el-menu-item index="7-1">通知查看</el-menu-item>
                        <el-menu-item index="7-2">通知发布</el-menu-item>
                    </el-sub-menu>
                    <el-sub-menu index="8" popper-class="custom-dropdown">
                        <template #title>用户管理</template>
                        <el-menu-item index="8-1">用户管理</el-menu-item>
                        <el-menu-item index="8-2">角色管理</el-menu-item>
                    </el-sub-menu>
                </el-menu>
            </div>
            <div class="user-section" id="userSection">
                <span class="user-name">管理员</span>
                <svg class="user-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
            </div>
            <div class="user-dropdown" id="userDropdown" style="display:none; position:absolute; top:60px; right:24px; width:160px; background:#fff; border:1px solid var(--border-light); border-radius:2px; box-shadow:0 4px 12px rgba(0,0,0,0.08); overflow:hidden; z-index:200;">
                <div class="item" style="padding:10px 12px; color:var(--text-secondary); cursor:pointer;">个人中心</div>
                <div class="item" style="padding:10px 12px; color:var(--text-secondary); cursor:pointer;">退出登录</div>
            </div>
        </header>

        <div class="main-content">
            <section class="combined-header">
                <h1 class="page-title">通知管理</h1>
                <div class="filter-container">
                    <div class="search-box">
                        <svg class="search-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
                        <input id="keyword" type="text" placeholder="搜索通知...">
                    </div>
                    <select id="typeFilter" class="select">
                        <option value="all">通知类型: 全部</option>
                        <option value="normal">普通</option>
                        <option value="important">重要</option>
                        <option value="urgent">紧急</option>
                    </select>
                    <input id="startDate" class="date-input" type="date" placeholder="开始日期">
                    <span class="date-separator">至</span>
                    <input id="endDate" class="date-input" type="date" placeholder="结束日期">
                    <select id="statusFilter" class="select">
                        <option value="all">状态: 全部</option>
                        <option value="published">已发布</option>
                        <option value="scheduled">定时</option>
                        <option value="draft">草稿</option>
                    </select>
                    <button id="queryBtn" class="btn btn-primary">查询</button>
                    <button id="resetBtn" class="btn btn-default">重置</button>
                    <button id="createBtn" class="btn btn-primary">发布通知</button>
                </div>
            </section>

            <section class="table-section">
                <div class="table-container">
                    <table class="data-table">
                        <thead>
                            <tr>
                                <th>通知标题</th>
                                <th>通知类型</th>
                                <th>发布时间</th>
                                <th>发布状态</th>
                                <th>阅读统计</th>
                                <th>操作</th>
                            </tr>
                        </thead>
                        <tbody id="noticeBody"></tbody>
                    </table>
                </div>
                <div class="table-footer">
                    <div class="pagination-text">共 <span id="totalRecords">0</span> 条记录</div>
                    <div class="pagination-controls">
                        <div id="pageNumbers" class="page-numbers"></div>
                        <div class="pagination-size">
                            每页显示
                            <select id="pageSizeSelector" class="page-size-selector">
                                <option value="10">10</option>
                                <option value="20">20</option>
                                <option value="50">50</option>
                            </select>
                            条
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </div>

    <!-- 发布通知弹窗 -->
    <div id="publishModal" class="modal-overlay">
        <div class="modal">
            <div class="modal-header">
                <h3 class="modal-title">发布通知</h3>
                <button class="modal-close" id="closePublish">×</button>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label class="form-label" for="noticeTitle">通知标题</label>
                    <input id="noticeTitle" class="form-control" placeholder="请输入通知标题">
                </div>
                <div class="form-group">
                    <label class="form-label">通知类型</label>
                    <select id="noticeType" class="form-control">
                        <option value="normal">普通</option>
                        <option value="important">重要</option>
                        <option value="urgent">紧急</option>
                    </select>
                </div>
                <div class="form-group">
                    <label class="form-label">通知对象（可多选）</label>
                    <div class="native-multi-select" id="nativeTargets">
                        <div class="trigger" id="nativeTargetsTrigger">
                            <div class="tags" id="nativeTargetTags"></div>
                            <input id="nativeTargetsInput" class="input" placeholder="请选择通知对象" readonly>
                            <svg class="arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
                        </div>
                        <div class="dropdown" id="nativeTargetsDropdown" style="display:none;">
                            <div class="option" data-value="全体用户">
                                <input type="checkbox"> 全体用户
                            </div>
                            <div class="option" data-value="医生"><input type="checkbox"> 医生</div>
                            <div class="option" data-value="护士"><input type="checkbox"> 护士</div>
                            <div class="option" data-value="药剂科"><input type="checkbox"> 药剂科</div>
                            <div class="option" data-value="检验科"><input type="checkbox"> 检验科</div>
                            <div class="option" data-value="行政管理"><input type="checkbox"> 行政管理</div>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <label class="form-label" for="noticeContent">通知内容</label>
                    <div class="rte" id="noticeEditor">
                        <div class="rte-toolbar" id="rteToolbar">
                            <button type="button" class="rte-btn" data-cmd="bold"><b>B</b></button>
                            <button type="button" class="rte-btn" data-cmd="italic"><i>I</i></button>
                            <button type="button" class="rte-btn" data-cmd="underline"><u>U</u></button>
                            <span class="rte-sep"></span>
                            <button type="button" class="rte-btn" data-cmd="insertUnorderedList">• List</button>
                            <button type="button" class="rte-btn" data-cmd="insertOrderedList">1. List</button>
                            <span class="rte-sep"></span>
                            <button type="button" class="rte-btn" data-cmd="formatBlock" data-value="H1">H1</button>
                            <button type="button" class="rte-btn" data-cmd="formatBlock" data-value="H2">H2</button>
                            <button type="button" class="rte-btn" data-cmd="formatBlock" data-value="P">段落</button>
                            <span class="rte-sep"></span>
                            <button type="button" class="rte-btn" id="rteLink">链接</button>
                            <button type="button" class="rte-btn" id="rteImage">图片</button>
                            <button type="button" class="rte-btn" id="rteTable">表格</button>
                        </div>
                        <div class="rte-content" id="rteContent" contenteditable="true" placeholder="请输入通知内容..."></div>
                    </div>
                </div>
                <div class="form-group">
                    <label class="form-label">发布设置</label>
                    <div style="display:flex; gap:16px; align-items:center;">
                        <label style="display:flex; gap:8px; align-items:center;"><input type="radio" name="publishMode" value="now" checked> 立即发布</label>
                        <label style="display:flex; gap:8px; align-items:center;"><input type="radio" name="publishMode" value="schedule"> 定时发布</label>
                        <input id="scheduleTime" type="datetime-local" class="form-control" style="width:220px;" disabled>
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn btn-default" id="cancelPublish">取消</button>
                <button class="btn btn-primary" id="confirmPublish">确认发布</button>
            </div>
        </div>
    </div>

    <!-- 通知详情弹窗 -->
    <div id="detailModal" class="modal-overlay">
        <div class="modal" style="width: 800px;">
            <div class="modal-header">
                <h3 class="modal-title" id="detailTitle">通知详情</h3>
                <button class="modal-close" id="closeDetail">×</button>
            </div>
            <div class="modal-body" id="detailBody"></div>
            <div class="modal-footer">
                <button class="btn btn-default" id="closeDetailFooter">关闭</button>
            </div>
        </div>
    </div>

    <!-- 删除确认弹窗 -->
    <div id="deleteModal" class="modal-overlay">
        <div class="modal" style="width: 420px;">
            <div class="modal-header">
                <h3 class="modal-title">确认删除</h3>
                <button class="modal-close" id="closeDelete">×</button>
            </div>
            <div class="modal-body">
                <div style="text-align:center; color:var(--text-primary); margin-bottom:8px;">确定要删除该条通知吗？</div>
                <div style="text-align:center; color:var(--text-tertiary); font-size:12px;">该操作不可恢复</div>
            </div>
            <div class="modal-footer">
                <button class="btn btn-default" id="cancelDelete">取消</button>
                <button class="btn btn-primary" id="confirmDelete">确定删除</button>
            </div>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            const { createApp, ref } = Vue;
            const navApp = createApp({
                setup() {
                    const activeIndex = ref('7-1');
                    const handleSelect = (key, keyPath) => { console.log(key, keyPath); };
                    return { activeIndex, handleSelect };
                }
            });
            navApp.use(ElementPlus, { locale: ElementPlusLocaleZhCn });
            navApp.mount('#app-nav');

            const userSection = document.getElementById('userSection');
            const userDropdown = document.getElementById('userDropdown');
            if (userSection && userDropdown) {
                userSection.addEventListener('click', function(e) {
                    e.stopPropagation();
                    const isOpen = userDropdown.style.display === 'block';
                    userDropdown.style.display = isOpen ? 'none' : 'block';
                });
                document.addEventListener('click', function() { userDropdown.style.display = 'none'; });
            }

            // 模拟数据
            const notices = [
                { id: 'n001', title: '系统维护通知', type: 'urgent', datetime: '2025-09-28 10:00', status: 'published', read: 12, total: 20, targets: ['全体用户'], content: '系统将于本周日凌晨进行维护，届时服务短暂不可用。' },
                { id: 'n002', title: '新版本发布', type: 'important', datetime: '2025-09-25 14:30', status: 'published', read: 18, total: 20, targets: ['医生','护士'], content: '发布V2.3版本，优化性能并修复若干问题。' },
                { id: 'n003', title: '培训通知', type: 'normal', datetime: '2025-09-20 09:00', status: 'published', read: 15, total: 20, targets: ['全体用户'], content: '周三下午举行系统使用培训，请相关人员参加。' },
                { id: 'n004', title: '节假日安排', type: 'normal', datetime: '2025-09-30 09:00', status: 'scheduled', read: 0, total: 20, targets: ['全体用户'], content: '国庆放假安排通知，节后正常上班。' }
            ];

            // 状态
            let filtered = [...notices];
            let pageSize = 10; let currentPage = 1; let totalPages = 1;

            // DOM
            const keywordEl = document.getElementById('keyword');
            const typeEl = document.getElementById('typeFilter');
            const startEl = document.getElementById('startDate');
            const endEl = document.getElementById('endDate');
            const statusEl = document.getElementById('statusFilter');
            const queryBtn = document.getElementById('queryBtn');
            const resetBtn = document.getElementById('resetBtn');
            const createBtn = document.getElementById('createBtn');
            const bodyEl = document.getElementById('noticeBody');
            const totalEl = document.getElementById('totalRecords');
            const pagesEl = document.getElementById('pageNumbers');
            const pageSizeEl = document.getElementById('pageSizeSelector');

            function renderTable() {
                const start = (currentPage - 1) * pageSize;
                const end = start + pageSize;
                const pageData = filtered.slice(start, end);
                bodyEl.innerHTML = '';
                if (pageData.length === 0) {
                    const row = document.createElement('tr');
                    row.innerHTML = `<td colspan="6" class="empty-table-message">暂无通知</td>`;
                    bodyEl.appendChild(row);
                } else {
                    pageData.forEach(n => {
                        const row = document.createElement('tr');
                        row.innerHTML = `
                            <td>${n.title}</td>
                            <td>${typeLabel(n.type)}</td>
                            <td>${n.datetime}</td>
                            <td>${statusLabel(n.status)}</td>
                            <td>${n.read}/${n.total}</td>
                            <td>
                                <div class="operations">
                                    <a class="operation-link" data-op="detail" data-id="${n.id}">详情</a>
                                    <a class="operation-link" data-op="delete" data-id="${n.id}" style="color:var(--error);">删除</a>
                                </div>
                            </td>`;
                        bodyEl.appendChild(row);
                    });
                }
                totalEl.textContent = filtered.length;
                renderPagination();
            }

            function renderPagination() {
                totalPages = Math.ceil(filtered.length / pageSize) || 1;
                pagesEl.innerHTML = '';
                let start = Math.max(1, currentPage - 2);
                let end = Math.min(totalPages, start + 4);
                if (end - start < 4 && totalPages > 4) start = Math.max(1, end - 4);
                for (let i = start; i <= end; i++) {
                    const btn = document.createElement('button');
                    btn.textContent = i; btn.className = i === currentPage ? 'active' : '';
                    btn.addEventListener('click', () => { currentPage = i; renderTable(); });
                    pagesEl.appendChild(btn);
                }
            }

            function typeLabel(v){ return v==='urgent'?'紧急': v==='important'?'重要':'普通'; }
            function statusLabel(v){ return v==='published'?'已发布': v==='scheduled'?'定时':'草稿'; }

            function applyFilter(){
                const kw = keywordEl.value.trim().toLowerCase();
                const type = typeEl.value; const status = statusEl.value;
                const start = startEl.value; const end = endEl.value;
                filtered = notices.filter(n => {
                    const matchKw = kw ? (n.title.toLowerCase().includes(kw) || n.content.toLowerCase().includes(kw)) : true;
                    const matchType = type==='all' ? true : n.type===type;
                    const matchStatus = status==='all' ? true : n.status===status;
                    const date = n.datetime.slice(0,10);
                    const matchStart = start ? date >= start : true;
                    const matchEnd = end ? date <= end : true;
                    return matchKw && matchType && matchStatus && matchStart && matchEnd;
                });
                currentPage = 1; renderTable();
            }

            queryBtn.addEventListener('click', applyFilter);
            keywordEl.addEventListener('keypress', e => { if (e.key==='Enter') applyFilter(); });
            resetBtn.addEventListener('click', () => { keywordEl.value=''; typeEl.value='all'; statusEl.value='all'; startEl.value=''; endEl.value=''; currentPage=1; filtered=[...notices]; renderTable(); });
            pageSizeEl.addEventListener('change', () => { pageSize = parseInt(pageSizeEl.value, 10); currentPage = 1; renderTable(); });

            // 详情/删除代理
            document.addEventListener('click', function(e){
                const link = e.target.closest('a.operation-link');
                if (!link) return;
                const id = link.getAttribute('data-id');
                const op = link.getAttribute('data-op');
                if (op==='detail') openDetail(id);
                if (op==='delete') openDelete(id);
            });

            // 发布通知弹窗逻辑
            const publishModal = document.getElementById('publishModal');
            const closePublish = document.getElementById('closePublish');
            const cancelPublish = document.getElementById('cancelPublish');
            const confirmPublish = document.getElementById('confirmPublish');
            const scheduleTime = document.getElementById('scheduleTime');
            const noticeTitle = document.getElementById('noticeTitle');
            const noticeType = document.getElementById('noticeType');
            const nativeTargets = document.getElementById('nativeTargets');
            const nativeTargetsTrigger = document.getElementById('nativeTargetsTrigger');
            const nativeTargetsDropdown = document.getElementById('nativeTargetsDropdown');
            const nativeTargetsInput = document.getElementById('nativeTargetsInput');
            const nativeTargetTags = document.getElementById('nativeTargetTags');
            const rteContent = document.getElementById('rteContent');
            const rteToolbar = document.getElementById('rteToolbar');
            const rteLink = document.getElementById('rteLink');
            const rteImage = document.getElementById('rteImage');
            const rteTable = document.getElementById('rteTable');
            createBtn.addEventListener('click', () => { publishModal.style.display='flex'; });
            closePublish.addEventListener('click', () => publishModal.style.display='none');
            cancelPublish.addEventListener('click', () => publishModal.style.display='none');
            publishModal.addEventListener('click', e => { if (e.target===publishModal) publishModal.style.display='none'; });
            document.querySelectorAll('input[name="publishMode"]').forEach(r => r.addEventListener('change', function(){ scheduleTime.disabled = this.value!=='schedule'; }));
            confirmPublish.addEventListener('click', () => {
                const title = noticeTitle.value.trim(); if (!title) { alert('请输入通知标题'); return; }
                const contentHtml = rteContent.innerHTML.trim();
                const contentText = rteContent.textContent.trim();
                if (!contentText) { alert('请输入通知内容'); return; }
                const mode = document.querySelector('input[name="publishMode"]:checked').value;
                const id = 'n' + Math.random().toString().slice(2,6);
                const now = new Date();
                const pad = n=> String(n).padStart(2,'0');
                const dt = `${now.getFullYear()}-${pad(now.getMonth()+1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}`;
                const targets = (window.__targetsSelectValue && window.__targetsSelectValue.length) ? window.__targetsSelectValue.slice() : ['全体用户'];
                notices.unshift({ id, title, type: noticeType.value, datetime: mode==='schedule' && scheduleTime.value ? scheduleTime.value.replace('T',' ') : dt, status: mode==='schedule'?'scheduled':'published', read: 0, total: 0, targets, content: contentHtml });
                publishModal.style.display='none';
                noticeTitle.value=''; rteContent.innerHTML=''; scheduleTime.value='';
                if (window.__setTargetsSelectValue) window.__setTargetsSelectValue([]);
                applyFilter();
                alert('通知已提交');
            });

            // 富文本命令绑定
            if (rteToolbar) {
                rteToolbar.addEventListener('click', function(e){
                    const btn = e.target.closest('.rte-btn');
                    if (!btn) return;
                    const cmd = btn.getAttribute('data-cmd');
                    const val = btn.getAttribute('data-value');
                    rteContent.focus();
                    if (cmd === 'formatBlock') {
                        document.execCommand('formatBlock', false, val);
                    } else if (cmd) {
                        document.execCommand(cmd, false, null);
                    }
                });
                rteLink.addEventListener('click', function(){
                    const url = prompt('请输入链接地址');
                    if (url) { rteContent.focus(); document.execCommand('createLink', false, url); }
                });
                rteImage.addEventListener('click', function(){
                    const url = prompt('请输入图片地址');
                    if (url) { rteContent.focus(); document.execCommand('insertImage', false, url); }
                });
                rteTable.addEventListener('click', function(){
                    const rows = 2, cols = 2;
                    let html = '<table style="width:100%; border-collapse:collapse;">';
                    for (let r=0;r<rows;r++) {
                        html += '<tr>';
                        for (let c=0;c<cols;c++) html += '<td style="border:1px solid var(--border-light); padding:6px;">&nbsp;</td>';
                        html += '</tr>';
                    }
                    html += '</table>';
                    rteContent.focus();
                    document.execCommand('insertHTML', false, html);
                });
            }

            // 原生多选下拉（不收起多选、标签回显、外部点击关闭、全体用户互斥）
            (function initNativeMultiSelect(){
                if (!nativeTargets) return;
                const options = ['全体用户','医生','护士','药剂科','检验科','行政管理'];
                const selected = [];
                window.__targetsSelectValue = selected;
                window.__setTargetsSelectValue = (arr)=>{ selected.splice(0, selected.length, ...arr); renderTags(); renderDropdown(); };

                function isAllSelected(){ return selected.includes('全体用户'); }
                function toggle(value){
                    if (value === '全体用户') {
                        selected.splice(0, selected.length, '全体用户');
                    } else {
                        if (isAllSelected()) selected.splice(0, selected.length);
                        const idx = selected.indexOf(value);
                        if (idx > -1) selected.splice(idx,1); else selected.push(value);
                    }
                    renderTags(); renderDropdown();
                }
                function removeTag(value){
                    const idx = selected.indexOf(value);
                    if (idx > -1) selected.splice(idx,1);
                    renderTags(); renderDropdown();
                }
                function renderTags(){
                    nativeTargetTags.innerHTML = '';
                    if (selected.length === 0) {
                        nativeTargetsInput.placeholder = '请选择通知对象';
                    } else {
                        nativeTargetsInput.placeholder = '';
                    }
                    selected.forEach(v => {
                        const tag = document.createElement('span');
                        tag.className = 'tag';
                        tag.innerHTML = `${v}<span class="remove" data-val="${v}">×</span>`;
                        nativeTargetTags.appendChild(tag);
                    });
                }
                function renderDropdown(){
                    const items = nativeTargetsDropdown.querySelectorAll('.option');
                    items.forEach(item => {
                        const val = item.getAttribute('data-value');
                        const cb = item.querySelector('input[type="checkbox"]');
                        const disabled = isAllSelected() && val !== '全体用户';
                        item.classList.toggle('selected', selected.includes(val));
                        if (cb) { cb.checked = selected.includes(val); cb.disabled = disabled; }
                    });
                }
                // 打开/关闭
                nativeTargetsTrigger.addEventListener('click', function(e){
                    e.stopPropagation();
                    const open = nativeTargetsDropdown.style.display === 'block';
                    nativeTargetsDropdown.style.display = open ? 'none' : 'block';
                });
                document.addEventListener('click', function(){ nativeTargetsDropdown.style.display = 'none'; });
                // 选项点击（不收起）
                nativeTargetsDropdown.addEventListener('click', function(e){
                    const opt = e.target.closest('.option');
                    if (!opt) return;
                    const val = opt.getAttribute('data-value');
                    toggle(val);
                    e.stopPropagation();
                });
                // 标签移除
                nativeTargets.addEventListener('click', function(e){
                    const rm = e.target.closest('.remove');
                    if (!rm) return;
                    removeTag(rm.getAttribute('data-val'));
                    e.stopPropagation();
                });
                // 初始渲染
                renderTags(); renderDropdown();
            })();

            // 详情弹窗
            const detailModal = document.getElementById('detailModal');
            const detailTitle = document.getElementById('detailTitle');
            const detailBody = document.getElementById('detailBody');
            const closeDetail = document.getElementById('closeDetail');
            const closeDetailFooter = document.getElementById('closeDetailFooter');
            function openDetail(id){
                const n = notices.find(x => x.id===id); if (!n) return;
                const percent = n.total ? Math.round((n.read / n.total) * 100) : 0;
                detailTitle.textContent = n.title;
                detailBody.innerHTML = `
                    <div class="detail-grid">
                        <div class="detail-item"><div class="label">通知类型</div><div class="value">${typeLabel(n.type)}</div></div>
                        <div class="detail-item"><div class="label">发布时间</div><div class="value">${n.datetime}</div></div>
                        <div class="detail-item"><div class="label">发布状态</div><div class="value">${statusLabel(n.status)}</div></div>
                        <div class="detail-item"><div class="label">通知对象</div><div class="value">${(n.targets && n.targets.length ? n.targets.join('、') : '全体用户')}</div></div>
                        <div class="detail-item"><div class="label">阅读统计</div><div class="value">${n.read}/${n.total}（${percent}%）</div></div>
                    </div>
                    <div class="label" style="margin-bottom:8px; color: var(--text-tertiary); font-size: 12px;">通知内容</div>
                    <div class="content-box">${n.content}</div>
                `;
                detailModal.style.display='flex';
            }
            closeDetail.addEventListener('click', ()=> detailModal.style.display='none');
            closeDetailFooter.addEventListener('click', ()=> detailModal.style.display='none');
            detailModal.addEventListener('click', e => { if (e.target===detailModal) detailModal.style.display='none'; });

            // 删除确认
            const deleteModal = document.getElementById('deleteModal');
            const closeDelete = document.getElementById('closeDelete');
            const cancelDelete = document.getElementById('cancelDelete');
            const confirmDelete = document.getElementById('confirmDelete');
            let deleteId = null;
            function openDelete(id){ deleteId = id; deleteModal.style.display='flex'; }
            closeDelete.addEventListener('click', ()=> deleteModal.style.display='none');
            cancelDelete.addEventListener('click', ()=> deleteModal.style.display='none');
            deleteModal.addEventListener('click', e => { if (e.target===deleteModal) deleteModal.style.display='none'; });
            confirmDelete.addEventListener('click', ()=>{ if(deleteId){ const idx = notices.findIndex(n=>n.id===deleteId); if(idx>-1) notices.splice(idx,1); deleteModal.style.display='none'; applyFilter(); }});

            // 初始化
            applyFilter();
        });
    </script>
</body>
</html>


